#include <assert.h>
#include <iostream>
using std::cout;
using std::endl;

template <class T>
class Singleton
{
    class AutoRelease
    {
    public:
        AutoRelease() { cout << "AutoRelease()" << endl;    }
        ~AutoRelease() {
            if(_pInstance) {
                delete _pInstance;
                _pInstance = nullptr;
                cout << "~AutoRelease()" << endl;
            }
        }

    };
public:
    template <class... Args>
    static T * getInstance(Args... args)
    {
        _auto;//如果不出现_auto对象，编译器就无法推导
        if(nullptr == _pInstance) {
            _pInstance = new T(args...);
        }
        return _pInstance;
    }

private:
    Singleton() {}
    ~Singleton() {}

private:
    static T * _pInstance;
    static AutoRelease _auto;
};

template <class T>
//T * Singleton<T>::_pInstance = nullptr;
T * Singleton<T>::_pInstance = getInstance();

//在getInstance的实现中，如果没有_auto对象的出现，
//以下这一句无法正常推导
template <class T>
class Singleton<T>::AutoRelease Singleton<T>::_auto;

class Point
{
public:
    Point(int ix = 0, int iy = 0)
    : _ix(ix)
    , _iy(iy)
    {   cout << "Point(int,int)" << endl;    }

    ~Point()
    {   cout << "~Point()" << endl; }  

    //二段式构造
    void init(int ix, int iy)
    {
        _ix = ix;
        _iy = iy;
    }

    void print() const 
    {
        cout << "(" << _ix
             << "," << _iy
             << ")" << endl;
    }

private:
    int _ix;
    int _iy;
};

void test0()
{
    Point * pt1 = Singleton<Point>::getInstance();
    Point * pt2 = Singleton<Point>::getInstance();
    pt1->init(1, 2);
    pt1->print();
    cout << "pt1:" << pt1 << endl;
    cout << "pt2:" << pt2 << endl;
    assert(pt1 == pt2);
}


int main()
{
    test0();
    return 0;
}

